import { zodResolver } from '@hookform/resolvers/zod'
import {
	Button,
	Card,
	CardActions,
	CardContent,
	CircularProgress,
	Skeleton,
	Typography
} from '@mui/material'
import Grid from '@mui/material/Unstable_Grid2'
import { useMutation, useQueryClient } from '@tanstack/react-query'
import { Eraser, FilePen, FilePlus2, Pencil, Save, Trash } from 'lucide-react'
import { useRouter } from 'next/navigation'
import { useCallback, useEffect, useState } from 'react'
import { useForm } from 'react-hook-form'
import { toast } from 'sonner'

import { ConfirmationDialog } from '@/components/dialogs/confirmation.dialog'
import { DateTimeControlled } from '@/components/forms/DateTimeControlled'
import { SelectFieldControlled } from '@/components/forms/SelectFieldControlled'
import { TextFieldControlled } from '@/components/forms/TextFieldControlled'

import {
	type ITask,
	type ITaskForm,
	taskFormScheme,
	taskStatuses
} from '@/types/task.types'

import { DASHBOARD_PAGES } from '@/config/pages-url.config'

import { taskService } from '@/services/tasks.service'

export function TaskCard({
	task_data,
	createMode
}: {
	task_data: ITask | undefined
	createMode?: boolean
}) {
	const queryClient = useQueryClient()
	const router = useRouter()

	const [task, setTask] = useState<ITask | undefined>(task_data)
	const [editMode, setEditMode] = useState<boolean>(createMode ?? false)
	const [showDeleteConfDialog, setShowDeleteConfDialog] =
		useState<boolean>(false)

	const {
		formState: { isDirty, isValid, errors },
		handleSubmit,
		reset,
		control
	} = useForm<ITaskForm>({
		mode: 'onChange',
		resolver: zodResolver(taskFormScheme),
		defaultValues: task
	})

	useEffect(() => {
		console.log(errors)
	}, [errors])

	useEffect(() => {
		setTask(task_data)
		reset(task_data)
	}, [task_data])

	const updateTask = useMutation({
		mutationKey: ['task', 'update', task?.id],
		mutationFn: (data: ITaskForm) => taskService.update(task?.id!, data),
		onSuccess: data => {
			setEditMode(false)
			setTask(data)
			queryClient.setQueryData(['task', data.id], data)
			queryClient.invalidateQueries({ queryKey: ['tasks'] })
			reset(data)
			toast.success('Изменения сохранены')
		},
		onError: () => {
			toast.error('Ошибка сохранения')
		}
	})

	const createTask = useMutation({
		mutationKey: ['task', 'create'],
		mutationFn: (data: ITaskForm) => taskService.create(data),
		onSuccess: data => {
			setTask(data)
			reset(data)
			queryClient.invalidateQueries({ queryKey: ['tasks'] })
			queryClient.setQueryData(['request', data.id], data)

			router.push(`${DASHBOARD_PAGES.TASK}${data.id}`)

			toast.success(`Задача создана`, {
				description: `"${data.title}" #${data.id}`
			})
		},
		onError: () => {
			toast.error('Ошибка создания')
		}
	})

	const deleteTask = useMutation({
		mutationKey: ['task', 'delete', task?.id],
		mutationFn: () => taskService.del(task?.id!),
		onSuccess: () => {
			queryClient.invalidateQueries({
				queryKey: ['task', task?.id]
			})
			queryClient.invalidateQueries({ queryKey: ['tasks'] })

			router.back()
			toast.success('Задача удалена', {
				description: `"${task?.title}" #${task?.id}`
			})
		}
	})

	const isPending =
		updateTask.isPending || deleteTask.isPending || createTask.isPending

	const enableEditMode = useCallback(
		() => !createMode && setEditMode(true),
		[createMode]
	)
	const declineEditMode = useCallback(() => {
		if (!createMode) setEditMode(false)
		reset(task)
	}, [task])

	const handleDelete = useCallback(() => {
		deleteTask.mutate()
	}, [deleteTask])

	const onSubmit = useCallback(
		(data: ITaskForm) =>
			createMode ? createTask.mutate(data) : updateTask.mutate(data),
		[createMode, createTask, updateTask]
	)

	return (
		<Card>
			<form noValidate>
				<CardContent>
					<Typography
						variant='h5'
						component='div'
					>
						{task ? (
							createMode ? (
								'Новая задача'
							) : (
								`Задача #${task.id}`
							)
						) : (
							<Skeleton />
						)}
					</Typography>
					{!createMode && (
						<Typography
							sx={{ mb: 1.5, display: 'flex' }}
							color='text.secondary'
						>
							<FilePlus2
								size={18}
								style={{ marginRight: 4 }}
							/>
							{task ? (
								task.created_on.format('HH:mm DD.MM.YYYY')
							) : (
								<Skeleton width={60} />
							)}
							;
							<FilePen
								size={18}
								style={{ marginRight: 4, marginLeft: 4 }}
							/>
							{task ? (
								task.updated_on.format('HH:mm DD.MM.YYYY')
							) : (
								<Skeleton width={60} />
							)}
						</Typography>
					)}
					{task ? (
						<Grid
							container
							spacing={2}
						>
							<Grid xs={'auto'}>
								<TextFieldControlled
									control={control}
									name='title'
									label='Название задачи'
									readOnly={!editMode}
									disabled={isPending}
									onDoubleClick={enableEditMode}
								/>
							</Grid>

							<Grid xs={'auto'}>
								<SelectFieldControlled
									control={control}
									name='status'
									label='Статус'
									options={Object.entries(taskStatuses).map(([key, value]) => ({
										id: Number(key),
										name: value
									}))}
									readOnly={!editMode}
									disabled={isPending}
									onDoubleClick={enableEditMode}
								/>
							</Grid>

							<Grid xs={6}>
								<TextFieldControlled
									control={control}
									name='description'
									label='Описание'
									readOnly={!editMode}
									disabled={isPending}
									onDoubleClick={enableEditMode}
									multiline
								/>
							</Grid>

							<Grid xs={6}>
								<TextFieldControlled
									control={control}
									name='note'
									label='Примечание'
									readOnly={!editMode}
									disabled={isPending}
									onDoubleClick={enableEditMode}
									multiline
								/>
							</Grid>

							<Grid xs={6}>
								<DateTimeControlled
									control={control}
									name='deadline'
									label='Крайний срок'
									readOnly={!editMode}
									disabled={isPending}
								/>
							</Grid>
						</Grid>
					) : (
						<Skeleton
							variant='rectangular'
							height={300}
						/>
					)}
				</CardContent>
				<CardActions>
					{task && !createMode && (
						<ConfirmationDialog
							open={showDeleteConfDialog}
							title={'Вы уверены, что хотите УДАЛИТЬ эту ЗАДАЧУ?'}
							onConfirm={handleDelete}
							onClose={() => setShowDeleteConfDialog(false)}
						/>
					)}
					{task && !editMode && !createMode && (
						<>
							<Button
								size='small'
								startIcon={<Pencil size={20} />}
								onClick={enableEditMode}
							>
								Редактировать
							</Button>
							<Button
								size='small'
								color={'error'}
								startIcon={<Trash size={20} />}
								onClick={() => setShowDeleteConfDialog(true)}
								disabled={isPending}
							>
								Удалить
							</Button>
						</>
					)}
					{editMode && (
						<Button
							size='small'
							color={'success'}
							startIcon={<Save size={20} />}
							onClick={handleSubmit(onSubmit)}
							disabled={isPending || !isDirty || !isValid}
						>
							Сохранить
						</Button>
					)}
					{editMode && (
						<Button
							size='small'
							color={'error'}
							startIcon={<Eraser size={20} />}
							onClick={declineEditMode}
							disabled={isPending}
						>
							{createMode ? 'Очистить' : 'Отменить'}
						</Button>
					)}
					{isPending && <CircularProgress size={20} />}
				</CardActions>
			</form>
		</Card>
	)
}
